<template>
  <div class="file-list">
    <!-- 顶部操作栏 -->
    <div class="action-bar">
      <el-breadcrumb separator="/">
        <el-breadcrumb-item v-if="!currentDirectory">根目录</el-breadcrumb-item>
        <el-breadcrumb-item v-else>{{ currentDirectory.name }}</el-breadcrumb-item>
      </el-breadcrumb>

      <div class="upload-group">
        <el-upload
            class="upload-btn"
            ref="upload"
            :auto-upload="false"
            :on-change="handleFileSelect"
            :before-upload="validateFile"
        >
          <el-button type="primary" icon="el-icon-upload">选择文件</el-button>
        </el-upload>

        <el-button
            v-if="selectedFile"
            type="info"
            icon="el-icon-close"
            @click="cancelFileSelect"
            style="margin-left: 10px"
        >
          取消选择
        </el-button>

        <el-button
            type="success"
            icon="el-icon-upload2"
            @click="submitUpload"
            :disabled="!selectedFile || loading.upload"
            style="margin-left: 10px"
        >
          <i v-if="loading.upload" class="el-icon-loading"></i>
          <span v-else>确认上传</span>
        </el-button>
      </div>
    </div>

    <!-- 空状态容器 -->
    <div
        v-if="!currentDirectory || files.length === 0"
        class="empty-container"
    >
      <div v-if="!currentDirectory" class="empty-tip">
        <i class="el-icon-folder-add" style="font-size: 60px; margin-bottom: 20px;"></i>
        <p class="title">请选择左侧文件夹</p>
        <p class="desc">点击左侧的文件夹名称，即可查看或管理对应目录下的文件</p>
      </div>
      <div v-else class="empty-tip">
        <i class="el-icon-document-empty" style="font-size: 60px; margin-bottom: 20px;"></i>
        <p class="title">当前目录暂无文件</p>
        <p class="desc">可通过上方“选择文件”按钮上传新文件到当前目录</p>
      </div>
    </div>

    <!-- 文件列表表格 -->
    <el-table
        v-if="currentDirectory && files.length > 0"
        :data="files"
        style="width: 100%"
        stripe
        :row-key="row => row.path"
    >
      <el-table-column label="文件名" min-width="300">
        <template slot-scope="scope">
          <el-button
              type="text"
              @click="downloadFile(scope.row)"
              :icon="getFileIcon(scope.row.name)"
          >
            {{ scope.row.name }}
          </el-button>
        </template>
      </el-table-column>
      <el-table-column label="大小" prop="size" min-width="100">
        <template slot-scope="scope">
          {{ formatFileSize(scope.row.size) }}
        </template>
      </el-table-column>
      <el-table-column label="操作" min-width="100">
        <template slot-scope="scope">
          <el-button
              size="mini"
              type="danger"
              @click="deleteFile(scope.row)"
              :loading="loading.delete"
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页组件 -->
    <file-pagination
        v-show="currentDirectory && total > 0"
        :total="total"
        :page.sync="listQuery.page"
        :limit.sync="listQuery.limit"
        @pagination="fetchFiles"
    />
  </div>
</template>

<script>
// 引入接口请求方法（需根据实际项目路径调整）
import { getFileList, uploadFile, downloadFile, deleteFile } from '@/api/document';
// 引入分页组件（需根据实际组件路径调整）
import FilePagination from './FilePagination.vue';
// 引入 lodash 的防抖函数
import { debounce } from 'lodash';

export default {
  name: 'FileList',
  components: {
    FilePagination
  },
  props: {
    currentDirectory: {
      type: Object,
      default: null
    }
  },
  data() {
    return {
      files: [],
      total: 0,
      listQuery: {
        page: 1,
        limit: 20
      },
      selectedFile: null,
      loading: {
        list: false,
        upload: false,
        download: false,
        delete: false
      },
      acceptTypes: '.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.pdf,.txt,.zip,.rar'
    };
  },
  created() {
    if (this.currentDirectory) {
      this.fetchFiles();
    }
  },
  beforeDestroy() {
    // 清理资源
    const downloadLink = document.querySelector('a[download]');
    if (downloadLink) {
      window.URL.revokeObjectURL(downloadLink.href);
      document.body.removeChild(downloadLink);
    }
    // 清除防抖计时器
    if (this._directoryWatch) {
      this._directoryWatch.cancel();
    }
  },
  watch: {
    // 使用闭包存储防抖函数，便于销毁
    currentDirectory: {
      handler: function(newVal) {
        if (newVal) {
          this.listQuery.page = 1;
          this.fetchFiles();
        }
      },
      deep: true,
      immediate: false
    }
  },
  computed: {
    // Vue 2 中实现类似 Vue 3 的防抖效果
    _directoryWatch() {
      return debounce(this.fetchFiles, 300);
    }
  },
  methods: {
    // 获取文件列表
    async fetchFiles() {
      if (!this.currentDirectory?.path) {
        this.$message.warning('目录路径无效');
        return;
      }

      this.loading.list = true;
      try {
        const res = await getFileList({
          directory: this.currentDirectory.path,
          page: this.listQuery.page,
          limit: this.listQuery.limit
        });

        if (!Array.isArray(res.data)) {
          throw new Error('文件列表格式错误（预期数组）');
        }
        this.files = res.data;
        this.total = typeof res.total === 'number' ? res.total : res.data.length;
      } catch (error) {
        console.error('获取文件列表失败:', error);
        this.$message.error(`获取文件列表失败：${error.message || '网络错误'}`);
      } finally {
        this.loading.list = false;
      }
    },

    // 处理文件选择
    handleFileSelect(file) {
      this.selectedFile = file.raw;
      this.$message.info(`已选择文件：${file.name}`);
    },

    // 取消文件选择
    cancelFileSelect() {
      this.selectedFile = null;
      this.$refs.upload.clearFiles();
      this.$message.info('已取消文件选择');
    },

    // 提交文件上传
    async submitUpload() {
      if (!this.selectedFile) {
        this.$message.warning('请选择文件');
        return;
      }

      this.loading.upload = true;
      try {
        const formData = new FormData();
        formData.append('file', this.selectedFile);
        formData.append('directory', this.currentDirectory.path);
        await uploadFile(formData);
        this.$message.success('文件上传成功！');
        this.fetchFiles();
        this.selectedFile = null;
        this.$refs.upload.clearFiles();
      } catch (error) {
        this.$message.error(`上传失败：${error.response?.data?.message || error.message}`);
      } finally {
        this.loading.upload = false;
      }
    },

    // 校验文件
    validateFile(file) {
      const isLt100M = file.size / 1024 / 1024 < 100;
      if (!isLt100M) {
        this.$message.error('文件大小不能超过 100MB');
        return false;
      }

      const fileName = file.name.toLowerCase();
      const isTypeValid = this.acceptTypes.split(',').some(type =>
          fileName.endsWith(type.toLowerCase())
      );
      if (!isTypeValid) {
        this.$message.error(`仅支持以下文件类型：${this.acceptTypes}`);
        return false;
      }

      return true;
    },

    // 下载文件
    downloadFile(file) {
      this.loading.download = true;
      this.$message.info(`正在下载 ${file.name}...`);

      downloadFile(file.path)
          .then(({ data }) => {
            const downloadUrl = window.URL.createObjectURL(data);
            const a = document.createElement('a');
            a.href = downloadUrl;
            a.download = file.name;
            document.body.appendChild(a);
            a.click();
            a.remove();
            window.URL.revokeObjectURL(downloadUrl);
            this.$message.success(`《${file.name}》下载成功`);
          })
          .catch((error) => {
            this.$message.error(`下载失败：${error.message || '文件不存在'}`);
          })
          .finally(() => {
            this.loading.download = false;
          });
    },

    // 删除文件
    async deleteFile(file) {
      try {
        await this.$confirm(
            `确定删除文件《${file.name}》吗？删除后不可恢复`,
            '确认删除',
            {
              confirmButtonText: '删除',
              cancelButtonText: '取消',
              type: 'warning'
            }
        );

        this.loading.delete = true;
        await deleteFile(file.path);
        this.$message.success('文件删除成功');
        this.fetchFiles();
      } catch (error) {
        if (error !== 'cancel') {
          this.$message.error(`删除失败：${error.message}`);
        }
      } finally {
        this.loading.delete = false;
      }
    },

    // 获取文件图标
    getFileIcon(fileName) {
      const ext = fileName.split('.').pop()?.toLowerCase() || '';
      const iconMap = {
        'jpg': 'el-icon-picture',
        'jpeg': 'el-icon-picture',
        'png': 'el-icon-picture',
        'gif': 'el-icon-picture',
        'doc': 'el-icon-document',
        'docx': 'el-icon-document',
        'xls': 'el-icon-document',
        'xlsx': 'el-icon-document',
        'pdf': 'el-icon-document',
        'txt': 'el-icon-document',
        'zip': 'el-icon-folder-opened',
        'rar': 'el-icon-folder-opened'
      };
      return iconMap[ext] || 'el-icon-document';
    },

    // 格式化文件大小
    formatFileSize(bytes) {
      if (typeof bytes !== 'number' || isNaN(bytes) || bytes <= 0) return '0 B';
      const k = 1024;
      const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }
  }
};
</script>

<style scoped>
.file-list {
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 20px;
}

.action-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  flex-wrap: wrap;
  gap: 10px;
}

.upload-group {
  display: flex;
  align-items: center;
}

.upload-btn {
  display: inline-block;
}

.empty-container {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  color: #999;
}

.empty-tip {
  max-width: 400px;
}

.empty-tip .title {
  font-size: 16px;
  font-weight: 500;
  margin: 10px 0;
  color: #333;
}

.empty-tip .desc {
  font-size: 14px;
  line-height: 1.6;
}

.el-table {
  flex: 1;
  margin-bottom: 20px;
}
</style>